import 'dart:async';
import 'dart:typed_data';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';

class BluetoothService {
  static final BluetoothService _instance = BluetoothService._internal();
  factory BluetoothService() => _instance;
  BluetoothService._internal();

  // 根据协议文档定义的 UUID
  static const String SERVICE_UUID = "0000fff0-0000-1000-8000-00805f9b34fb";
  static const String READ_NOTIFY_UUID = "0000fff1-0000-1000-8000-00805f9b34fb";
  static const String WRITE_UUID = "0000fff2-0000-1000-8000-00805f9b34fb";

  BluetoothDevice? _device;
  BluetoothCharacteristic? _txCharacteristic;
  BluetoothCharacteristic? _rxCharacteristic;
  StreamSubscription? _connectionSubscription;
  
  final StreamController<bool> _connectionStateController = StreamController<bool>.broadcast();
  Stream<bool> get connectionState => _connectionStateController.stream;
  
  bool get isConnected => _device != null && _txCharacteristic != null && _rxCharacteristic != null;

  // 扫描设备
  Future<void> startScan() async {
    if (!(await FlutterBluePlus.isSupported)) {
      throw Exception('设备不支持蓝牙');
    }

    final bluetoothState = await FlutterBluePlus.adapterState.first;
    if (bluetoothState != BluetoothAdapterState.on) {
      throw Exception('请打开蓝牙');
    }

    await FlutterBluePlus.startScan(
      timeout: const Duration(seconds: 4),
      androidUsesFineLocation: true,
    );
  }

  Future<void> stopScan() async {
    await FlutterBluePlus.stopScan();
  }

  Stream<List<ScanResult>> get scanResults => FlutterBluePlus.scanResults;

  // 连接设备
  Future<bool> connectToDevice(BluetoothDevice device) async {
    try {
      // 断开之前的连接
      await disconnect();
      
      // 连接新设备
      await device.connect(timeout: const Duration(seconds: 4));
      _device = device;

      // 监听连接状态
      _connectionSubscription = device.connectionState.listen((state) {
        final isConnected = state == BluetoothConnectionState.connected;
        _connectionStateController.add(isConnected);
        if (!isConnected) {
          _cleanup();
        }
      });
      
      // 获取服务
      List<BluetoothService> services = await device.discoverServices();
      var found = false;
      for (var service in services) {
        if (service.uuid.toString().toLowerCase() == SERVICE_UUID.toLowerCase()) {
          for (var characteristic in service.characteristics) {
            String charUuid = characteristic.uuid.toString().toLowerCase();
            if (charUuid == READ_NOTIFY_UUID.toLowerCase()) {
              _rxCharacteristic = characteristic;
              // 监听接收的数据
              await characteristic.setNotifyValue(true);
              characteristic.onValueReceived.listen(_handleReceivedData);
              found = true;
            }
            if (charUuid == WRITE_UUID.toLowerCase()) {
              _txCharacteristic = characteristic;
              found = true;
            }
          }
        }
      }

      if (!found) {
        throw Exception('设备不支持所需的蓝牙服务');
      }
      
      _connectionStateController.add(true);
      return true;
    } catch (e) {
      print('连接设备失败: $e');
      await disconnect();
      return false;
    }
  }

  // 断开连接
  Future<void> disconnect() async {
    await _cleanup();
    if (_device != null) {
      try {
        await _device!.disconnect();
      } catch (e) {
        print('断开连接时出错: $e');
      }
    }
    _device = null;
    _connectionStateController.add(false);
  }

  // 清理资源
  Future<void> _cleanup() async {
    _connectionSubscription?.cancel();
    _connectionSubscription = null;
    _txCharacteristic = null;
    _rxCharacteristic = null;
    stopHeartbeat();
  }

  // 处理接收到的数据
  void _handleReceivedData(List<int> data) {
    if (data.length < 5) return; // 数据包至少需要5个字节
    
    // 检查包头
    if (data[0] != 0x5A || data[1] != 0x6B) {
      print('无效的数据包头');
      return;
    }

    // 解析数据包
    int length = data[2];
    if (data.length != length + 5) { // 包头(2) + 长度(1) + 数据(n) + 校验(1) + 包尾(1)
      print('数据包长度不匹配');
      return;
    }

    // 检查包尾
    if (data[data.length - 1] != 0x05) {
      print('无效的数据包尾');
      return;
    }

    // 计算校验和
    int checksum = 0;
    for (int i = 0; i < data.length - 2; i++) {
      checksum ^= data[i];
    }
    if (checksum != data[data.length - 2]) {
      print('校验和不匹配');
      return;
    }

    // 解析命令字节
    int command = data[3];
    List<int> payload = data.sublist(4, data.length - 2);
    
    // 处理不同类型的命令
    switch (command) {
      case 0x01: // 按键状态
        _handleKeyStatus(payload);
        break;
      case 0x02: // 速度等级
        _handleSpeedLevel(payload);
        break;
      case 0x03: // 摇杆模式
        _handleControlMode(payload);
        break;
      default:
        print('未知的命令类型: 0x${command.toRadixString(16)}');
    }
  }

  // 处理按键状态
  void _handleKeyStatus(List<int> payload) {
    if (payload.isEmpty) return;
    int keyStatus = payload[0];
    bool forward = (keyStatus & 0x01) != 0;    // bit0: 前进
    bool backward = (keyStatus & 0x02) != 0;   // bit1: 后退
    bool left = (keyStatus & 0x04) != 0;       // bit2: 左转
    bool right = (keyStatus & 0x08) != 0;      // bit3: 右转
    bool stop = (keyStatus & 0x10) != 0;       // bit4: 停车
    // TODO: 处理按键状态
  }

  // 处理速度等级
  void _handleSpeedLevel(List<int> payload) {
    if (payload.isEmpty) return;
    int speedLevel = payload[0];
    // TODO: 处理速度等级
  }

  // 处理摇杆模式
  void _handleControlMode(List<int> payload) {
    if (payload.isEmpty) return;
    bool isShakeMode = payload[0] == 0x01;
    // TODO: 处理控制模式
  }

  // 构建数据包
  List<int> _buildPacket(int command, List<int> payload) {
    List<int> packet = [];
    packet.add(0x5A); // 包头1
    packet.add(0x6B); // 包头2
    packet.add(payload.length + 1); // 数据长度 (payload + command)
    packet.add(command); // 命令
    packet.addAll(payload); // 数据负载
    
    // 计算校验和
    int checksum = 0;
    for (int byte in packet) {
      checksum ^= byte;
    }
    packet.add(checksum); // 校验和
    packet.add(0x05); // 包尾
    
    return packet;
  }

  // 发送控制命令
  Future<bool> sendCommand(List<int> data) async {
    if (!isConnected || _txCharacteristic == null) {
      return false;
    }

    try {
      await _txCharacteristic!.write(data, withoutResponse: true);
      return true;
    } catch (e) {
      print('发送命令失败: $e');
      return false;
    }
  }

  // 发送心跳包
  Future<bool> sendHeartbeat() async {
    List<int> packet = _buildPacket(0x00, [0x00]);
    return sendCommand(packet);
  }

  // 发送飞行控制命令
  Future<bool> sendFlightControl({
    required double throttle,  // 油门 0.0-1.0
    required double pitch,     // 俯仰 -1.0-1.0
    required double roll,      // 滚转 -1.0-1.0
    required double yaw       // 偏航 -1.0-1.0
  }) async {
    // 将浮点数映射到0-255范围
    int throttleValue = (throttle.clamp(0.0, 1.0) * 255).round();
    int pitchValue = ((pitch.clamp(-1.0, 1.0) + 1.0) * 127.5).round();
    int rollValue = ((roll.clamp(-1.0, 1.0) + 1.0) * 127.5).round();
    int yawValue = ((yaw.clamp(-1.0, 1.0) + 1.0) * 127.5).round();

    List<int> payload = [
      throttleValue,  // 油门
      pitchValue,    // 俯仰
      rollValue,     // 滚转
      yawValue,      // 偏航
    ];
    
    List<int> packet = _buildPacket(0x04, payload);
    return sendCommand(packet);
  }

  // 发送紧急停止命令
  Future<bool> sendEmergencyStop() async {
    List<int> packet = _buildPacket(0x05, [0x01]);
    return sendCommand(packet);
  }

  // 发送校准命令
  Future<bool> sendCalibration() async {
    List<int> packet = _buildPacket(0x06, [0x01]);
    return sendCommand(packet);
  }

  // 开始心跳包定时发送
  Timer? _heartbeatTimer;
  
  void startHeartbeat() {
    _heartbeatTimer?.cancel();
    _heartbeatTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
      if (isConnected) {
        sendHeartbeat();
      } else {
        stopHeartbeat();
      }
    });
  }

  // 停止心跳包发送
  void stopHeartbeat() {
    _heartbeatTimer?.cancel();
    _heartbeatTimer = null;
  }

  // 资源释放
  void dispose() {
    disconnect();
    _connectionStateController.close();
  }
}
